package light.head.framework.fm;

import java.lang.reflect.Method;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;


/**
 * @author janhang
 * @2011-8-3 下午12:45:48
 */
@Service
public class EntityModel implements TemplateMethodModel, ApplicationContextAware {

	private ApplicationContext ctx;

	@SuppressWarnings("rawtypes")
	public Object exec(List args) throws TemplateModelException {
		if (null == args || args.size() < 1)
			return null;
		
		String objName = args.get(0).toString();
		String metName = "getAll";
		
		if (-1 == objName.indexOf("DAO"))
			objName += "DAO";
		if (args.size() > 1)
			metName = args.get(1).toString();
		
		Object dao = ctx.getBean(objName);
		Method m = getMethod(metName, dao.getClass());
		if (m == null) {
			System.out.println("调用EntityModel时，在" + objName + "中未找到方法：" + metName);
			return null;
		}
		Object result = null;
		try {
			// 最多只处理有3个参数需要传到DAO的情况，默认为没有参数
			switch (args.size()) {
				case 5: {
					result = m.invoke(dao, args.get(2), args.get(3), args.get(4));
					break;
				}
				case 4: {
					result = m.invoke(dao, args.get(2), args.get(3));
					break;
				}
				case 3: {
					result = m.invoke(dao, args.get(2));
					break;
				}
				default: {
					result = m.invoke(dao);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	@SuppressWarnings("rawtypes")
	private Method getMethod(String methodName, Class aClass) {
		Method[] methods = aClass.getMethods();
		
		for (Method m : methods) {
			// 这个判断已经固定DAO中被调用的这个方法不能被重载，否则悲剧
			if (m.getName().equals(methodName))// && 0 == m.getParameterTypes().length
				return m;
		}
		return null;
	}


	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		this.ctx = arg0;
	}
}
